package com.tqz.dt.parser;

import com.tqz.dt.anno.GlobalTransactional;
import com.tqz.dt.attribute.GlobalTransactionAttribute;
import com.tqz.dt.attribute.DefaultGlobalTransactionAttribute;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;

import java.lang.reflect.AnnotatedElement;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>自定义的注解解析器接口
 *
 * @author tianqingzhao
 * @since 2021/7/7 15:40
 */
public class GlobalSpringTransactionAnnotationParser implements GlobalTransactionAnnotationParser {

    @Override
    public GlobalTransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
        GlobalTransactional angleTransactionl = element.getAnnotation(GlobalTransactional.class);
        if (angleTransactionl != null) {
            return parseTransactionAnnotation(angleTransactionl);
        } else {
            return null;
        }
    }

    /**
     * 解析事务 {@link GlobalTransactional} 注解的属性
     *
     * @param angleTransactionl 事务注解的属性
     * @return 封装为 {@link DefaultGlobalTransactionAttribute} 返回
     */
    protected GlobalTransactionAttribute parseTransactionAnnotation(GlobalTransactional angleTransactionl) {
        DefaultGlobalTransactionAttribute defaultAngleTransactionAttribute = new DefaultGlobalTransactionAttribute();
        // 设置传播行为
        Propagation propagation = angleTransactionl.propagation();
        defaultAngleTransactionAttribute.setPropagationBehavior(propagation.value());
        // 设置隔离级别
        Isolation isolation = angleTransactionl.isolation();
        defaultAngleTransactionAttribute.setIsolationLevel(isolation.value());
        // 设置超时
        defaultAngleTransactionAttribute.setTimeout(angleTransactionl.timeout());
        // 设置只读事务
        defaultAngleTransactionAttribute.setReadOnly(angleTransactionl.readOnly());
        // 设置事务管理器
        defaultAngleTransactionAttribute.setTransactionManager(angleTransactionl.transactionManager());

        RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

        List<Class<?>> rollBackFor = new ArrayList<Class<?>>();
        for (Class<?> rollBackForEx : angleTransactionl.rollbackFor()) {
            rollBackFor.add(rollBackForEx);
        }
        // 设置对哪些异常回滚
        defaultAngleTransactionAttribute.setRollbackFor(rollBackFor);

        List<Class<?>> noRollbackFor = new ArrayList<Class<?>>();
        for (Class<?> norollBackForEx : angleTransactionl.noRollbackFor()) {
            noRollbackFor.add(norollBackForEx);
        }
        // 设置对哪些异常不回滚
        defaultAngleTransactionAttribute.setNoRollBackFor(noRollbackFor);
        return defaultAngleTransactionAttribute;
    }

}
